<template>
  <div class="canvas-container">
    <!-- 画板容器 -->
    <div class="canvas-wrapper" ref="canvasWrapper">
      <div id="canvas-container" ref="canvasContainer"></div>

      <!-- 右上角工具栏 -->
      <div class="toolbar">
        <button @click="exportJSON" class="toolbar-btn">导出JSON</button>
        <button @click="importJSON" class="toolbar-btn">导入JSON</button>
        <button @click="clearAll" class="toolbar-btn clear-btn">清空画布</button>
        <input ref="fileInput" type="file" accept=".json" @change="handleFileImport" style="display: none;">
      </div>

      <!-- 右键菜单 -->
      <div v-if="contextMenu.visible" class="context-menu"
        :style="{ left: contextMenu.x + 'px', top: contextMenu.y + 'px' }">
        <!-- 空白区域菜单 -->
        <template v-if="contextMenu.type === 'blank'">
          <div class="menu-item" @click="createNodeFromContextMenu">
            <span>新增独立节点</span>
          </div>
          <div class="menu-item" @click="hideContextMenu">
            <span>取消</span>
          </div>
        </template>

        <!-- 节点菜单 -->
        <template v-if="contextMenu.type === 'node'">
          <div class="menu-item" @click="addNodeWithAI">
            <span>新增ai节点</span>
          </div>
          <div class="menu-item" @click="reaskAI">
            <span>重新询问ai</span>
          </div>

          <div class="menu-item" @click="editNode">
            <span>编辑节点</span>
          </div>
          <div class="menu-item" @click="saveEditNode">
            <span>保存</span>
          </div>

          <div class="menu-item" @click="deleteNode">
            <span>删除节点</span>
          </div>

        </template>

        <!-- 编辑模式菜单 -->
        <template v-if="contextMenu.type === 'editing'">

          <div class="menu-item" @click="cancelEditNode">
            <span>取消保存</span>
          </div>
        </template>

        <!-- 线条菜单 -->
        <template v-if="contextMenu.type === 'edge'">
          <div class="menu-item" @click="deleteEdge">
            <span>删除线条</span>
          </div>

        </template>
      </div>
    </div>

    <!-- 底部输入区域 -->
    <div class="input-section">
      <div class="input-wrapper">
        <el-input v-model="inputText" placeholder="输入内容，AI将基于选中节点生成新节点..." class="ai-input" :disabled="isLoading"
          type="textarea" :rows="2" @keydown.native="handleKeydown" />
        <button @click="generateNode" class="generate-btn" :disabled="isLoading || !inputText.trim()">
          {{ isLoading ? '生成中...' : '生成节点' }}
        </button>
      </div>
      <div class="status-info">
        <span v-if="selectedNode">已选中节点: {{ selectedNode.label }}</span>
        <span v-else>未选中节点，将创建独立节点</span>
      </div>
    </div>

    <!-- 节点编辑弹窗 -->
    <NodeEditDialog :visible="isEditDialogVisible" :content="editContent" :nodeId="editingNodeId"
      @save="saveNodeContent" @close="closeEditDialog" />
  </div>
</template>

<script>
import { Graph, Shape } from '@antv/x6'
import { Selection } from '@antv/x6-plugin-selection'
import { Transform } from '@antv/x6-plugin-transform'
import { marked } from 'marked'
import { registerCustomNodes } from './canvasutils.js'
import NodeEditDialog from './NodeEditDialog.vue'
import EditableNodeController from './editableNodeController.js'
import { registerCustomConnector, registerEnhancedConnector } from './connectors/customConnector.js'
import { options } from 'marked'


export default {
  name: 'CanvasBoard',
  components: {
    NodeEditDialog
  },
  data() {
    return {
      // ，每一次 加入節點 這個都++1； 後續可以通過這個找到最後一個節點
      nodeOrderGlobe: 1,
      graph: null,
      inputText: '',
      isLoading: false,
      selectedNode: null,
      nodeCounter: 1,
      contextMenu: {
        visible: false,
        x: 0,
        y: 0,
        type: 'blank', // 菜单类型：'blank', 'node', 'edge'
        target: null   // 当前右键目标对象
      },
      // 连接状态管理
      connectionState: {
        isDragging: false,
        sourceNode: null,
        sourcePort: null,
        tempEdge: null,
        hoveredNode: null
      },
      // 编辑弹窗状态
      isEditDialogVisible: false,
      editContent: '',
      editingNodeId: null,
      // Transform控制状态
      transformEnabled: false, // Transform当前状态
      transformInstance: null // Transform插件实例引用
    }
  },

  mounted() {
    registerCustomNodes()
    // 注册自定义连接器
    registerCustomConnector(Graph)
    registerEnhancedConnector(Graph)
    this.initGraph()

    window._windowGraph = this;

    // 尝试从localStorage加载数据，如果没有数据则添加初始节点
    if (!this.loadCanvasFromStorage()) {
      this.addInitialNodes()
    }
  },

  methods: {
    /**
     * 初始化Transform插件
     */
    initializeTransform() {
      this.transformInstance = new Transform({
        resizing: {
          enabled: this.transformEnabled,
          minWidth: 100,
          minHeight: 60,
          maxWidth: 345,
          maxHeight: 666,
          orthogonal: true,
          restrict: false,
          preserveAspectRatio: false
        }
      })
      this.graph.use(this.transformInstance)
    },

    /**
     * 开启Transform
     */
    startResize() {
      this.transformEnabled = true
      this.updateTransformState()
      this.refreshNodeButtons()
      console.log('🔧 Transform已开启')
    },

    /**
     * 关闭Transform
     */
    stopResize() {
      this.transformEnabled = false
      this.updateTransformState()
      this.refreshNodeButtons()
      console.log('🔧 Transform已关闭')
    },

    /**
     * 刷新所有节点的按钮显示
     */
    refreshNodeButtons() {
      // 获取所有markdown节点
      const nodes = this.graph.getNodes().filter(node => node.shape === 'markdown-node')

      nodes.forEach(node => {
        // 移除现有的所有工具
        if (node.hasTool('button')) {
          node.removeTools()
        }

        // 重新添加编辑按钮
        node.addTools({
          name: 'button',
          args: {
            markup: [
              {
                tagName: 'circle',
                attrs: {
                  r: 14,
                  fill: '#007bff',
                  stroke: '#fff',
                  'stroke-width': 2,
                  cursor: 'pointer'
                }
              },
              {
                tagName: 'text',
                attrs: {
                  x: 0,
                  y: 0,
                  'text-anchor': 'middle',
                  'dominant-baseline': 'central',
                  fill: '#fff',
                  'font-size': 14,
                  'font-family': 'Arial',
                  cursor: 'pointer'
                },
                textContent: '✎'
              }
            ],
            x: '100%',
            y: 0,
            offset: { x: -8, y: 8 },
            onClick: ({ view }) => {
              const node = view.cell
              const nodeId = node.id || node.getId?.()
              const content = node.getData()?.content || ''
              this.openEditDialog(nodeId, content)
            }
          }
        })

        // 根据当前Transform状态添加相应的resize控制按钮
        if (this.transformEnabled) {
          node.addTools(this.createStopResizeButton())
        } else {
          node.addTools(this.createStartResizeButton())
        }
      })
    },

    /**
     * 更新Transform状态
     */
    updateTransformState() {
      if (this.transformInstance) {
        // 方法1: 重新配置插件
        this.transformInstance.options.resizing.enabled = this.transformEnabled

        // 如果方法1不生效，使用方法2: 重新注册插件
        if (!this.transformInstance.options.resizing.enabled === this.transformEnabled) {
          this.graph.unuse(this.transformInstance)
          this.initializeTransform()
        }
      }
    },

    /**
     * 处理键盘事件
     */
    handleKeydown(event) {
      // 检测Ctrl+Enter组合键
      if (event.ctrlKey && event.key === 'Enter') {
        event.preventDefault() // 阻止默认行为
        // 检查是否可以生成节点（不在加载中且有输入内容）
        if (!this.isLoading && this.inputText.trim()) {
          this.generateNode()
        }
      }
    },

    /**
     * 导出JSON
     */
    exportJSON() {
      try {
        const data = this.graph.toJSON()
        const jsonStr = JSON.stringify(data, null, 2)
        const blob = new Blob([jsonStr], { type: 'application/json' })
        const url = URL.createObjectURL(blob)
        const a = document.createElement('a')
        a.href = url
        a.download = `canvas-export-${Date.now()}.json`
        a.click()
        URL.revokeObjectURL(url)
        console.log('导出成功')
      } catch (error) {
        console.error('导出失败:', error)
        alert('导出失败')
      }
    },

    /**
     * 导入JSON
     */
    importJSON() {
      this.$refs.fileInput.click()
    },

    /**
     * 处理文件导入
     */
    handleFileImport(event) {
      const file = event.target.files[0]
      if (!file) return

      const reader = new FileReader()
      reader.onload = (e) => {
        try {
          const data = JSON.parse(e.target.result)
          this.graph.fromJSON(data)
          console.log('导入成功')
          // 导入成功后自动保存到localStorage
          this.saveCanvasToStorage()
        } catch (error) {
          console.error('导入失败:', error)
          alert('导入失败，请检查文件格式')
        }
      }
      reader.readAsText(file)

      // 清空input值，允许重复选择同一文件
      event.target.value = ''
    },

    /**
     * 保存画布数据到localStorage
     */
    saveCanvasToStorage() {
      try {
        const data = this.graph.toJSON()
        localStorage.setItem('vue-canvas-data', JSON.stringify(data))
        console.log('画布数据已保存到localStorage')
      } catch (error) {
        console.error('保存画布数据失败:', error)
      }
    },

    /**
     * 从localStorage加载画布数据
     */
    loadCanvasFromStorage() {
      try {
        const savedData = localStorage.getItem('vue-canvas-data')
        if (savedData) {
          const data = JSON.parse(savedData)
          this.graph.fromJSON(data)
          console.log('画布数据已从localStorage加载')
          // 加载数据后居中画布
          this.$nextTick(() => {
            this.centerCanvas()
          })
          return true
        }
      } catch (error) {
        console.error('加载画布数据失败:', error)
      }
      return false
    },

    /**
     * 居中画布内容
     */
    centerCanvas() {
      try {
        const nodes = this.graph.getNodes()
        if (nodes.length > 0) {
          // 计算所有节点的边界框
          const bbox = this.graph.getContentBBox()
          if (bbox) {
            // 获取画布容器尺寸
            const containerRect = this.graph.container.getBoundingClientRect()
            const containerWidth = containerRect.width
            const containerHeight = containerRect.height

            // 计算居中位置
            const centerX = (containerWidth - bbox.width) / 2 - bbox.x
            const centerY = (containerHeight - bbox.height) / 2 - bbox.y

            // 设置画布变换，使内容居中
            this.graph.centerContent()
            console.log('画布内容已居中')
          }
        }
      } catch (error) {
        console.error('居中画布失败:', error)
      }
    },

    /**
     * 清空所有内容
     */
    clearAll() {
      if (confirm('确定要清空画布和本地存储的所有内容吗？此操作不可撤销。')) {
        // 清空画布
        this.graph.clearCells()
        // 清空localStorage
        localStorage.removeItem('vue-canvas-data')
        // 重置计数器
        this.nodeOrderGlobe = 1
        this.nodeCounter = 1
        // 清空选中状态
        this.selectedNode = null
        console.log('画布和本地存储已清空')
      }
    },

    /**
     * 注册自定义HTML节点
     */
    /**
     * 初始化X6画板
     */
    initGraph() {
      // X6版本和环境检查
      console.log('🔍 X6环境检查:', {
        X6Version: Graph.version || 'unknown',
        hasGraph: !!Graph,
        hasShape: !!Shape,
        hasNodeTool: !!Graph.NodeTool,
        availableTools: Graph.NodeTool ? Object.keys(Graph.NodeTool) : 'NodeTool不可用'
      })

      this.graph = new Graph({
        container: this.$refs.canvasContainer,
        width: this.$refs.canvasWrapper.clientWidth,
        height: this.$refs.canvasWrapper.clientHeight,

        // 画板配置
        background: {
          color: '#f8f9fa'
        },

        // 网格配置
        grid: {
          visible: true,
          type: 'doubleMesh',
          args: [
            {
              color: '#e5e5e5',
              thickness: 1
            },
            {
              color: '#d0d0d0',
              thickness: 1,
              factor: 4
            }
          ]
        },

        // 缩放配置 - 需要Ctrl+滚轮才能缩放
        mousewheel: {
          enabled: true,
          zoomAtMousePosition: true,
          modifiers: ['ctrl'], // 需要按住Ctrl键才能滚轮缩放
          minScale: 0.1,
          maxScale: 5,
          factor: 1.1 // 缩放因子，控制缩放速度
        },

        // 拖拽配置 - 优化为更便捷的操作
        panning: {
          enabled: true,
          modifiers: [], // 移除修饰键，直接拖拽
          // eventTypes: ['leftMouseDown'] // 只响应左键拖拽
        },

        // 连接配置
        connecting: {
          router: {
            name: 'orth',
            args: {
              padding: 20, // 节点周围的间距
              maxAllowedDirectionChange: 90 // 最大允许的方向改变角度
            }
          },
          connector: {
            name: 'enhanced-smooth-connector',
            args: {
              curvature: 0.3,
              minDistance: 50,
              adaptiveControl: true,
              smoothness: 0.8
            }
          },
          anchor: 'center',
          connectionPoint: 'anchor',
          allowBlank: false,
          allowNode: true, // 允许连接到节点
          snap: {
            radius: 20
          },
          // createEdge() {
          //   return new Graph.Edge({
          //     attrs: {
          //       line: {
          //         stroke: '#5F95FF',
          //         strokeWidth: 2,
          //         targetMarker: {
          //           name: 'classic',
          //           size: 8
          //         }
          //       }
          //     },
          //     zIndex: 0
          //   })
          // }
        },

        // 高亮配置
        highlighting: {
          magnetAdsorbed: {
            name: 'stroke',
            args: {
              attrs: {
                fill: '#5F95FF',
                stroke: '#5F95FF'
              }
            }
          }
        },

        // 选择配置
        // selecting: {
        //   enabled: true,
        //   rubberband: true,
        //   movable: true,
        //   showNodeSelectionBox: true
        // },

        // 历史记录
        history: true,

        // 剪贴板
        clipboard: true,

        // 键盘快捷键
        keyboard: true,
      })

      this.graph.zoomToFit({ padding: 10, maxScale: 0.7 })


      console.log('📊 Graph实例创建完成:', {
        graphInstance: !!this.graph,
        graphMethods: {
          hasOn: typeof this.graph.on === 'function',
          hasFindViewByCell: typeof this.graph.findViewByCell === 'function'
        }
      })


      this.graph._onContentChange = ({ node }) => {
        this.saveCanvasToStorage()
      }

      this.graph.on('node:click', ({ node }) => {
        this.selectedNode = {
          id: node.id,
          label: node?.data?.content?.substring(0, 50) + '...'
        }

        //设置其他的 
        this.graph.getNodes().forEach((item) => {
          item?.attr({
            rect: {
              stroke: 'none',
            }

          })

        })
        node?.attr({
          rect: {
            stroke: '#5F95FF',
          }
        })
      })
      // 监听节点选择事件
      // this.graph.on('node:selected', ({ node }) => {
      //   this.selectedNode = {
      //     id: node.id,
      //     label: node.attr('label/text')
      //   }
      // })

      // 监听节点取消选择事件
      // this.graph.on('node:unselected', () => {
      //   this.selectedNode = null
      // })

      // 监听画板点击事件（取消选择）
      this.graph.on('blank:click', () => {
        this.graph.unselect(this.graph.getSelectedCells())
        this.selectedNode = null
        this.hideContextMenu()
      })

      // 监听画板右键事件
      this.graph.on('blank:contextmenu', ({ e }) => {
        e.preventDefault()
        this.showContextMenu(e.clientX, e.clientY, 'blank', null)
      })

      // 监听节点右键事件
      this.graph.on('node:contextmenu', ({ e, node }) => {
        e.preventDefault()
        this.showContextMenu(e.clientX, e.clientY, 'node', node)
      })

      // 监听线条右键事件
      this.graph.on('edge:contextmenu', ({ e, edge }) => {
        e.preventDefault()
        this.showContextMenu(e.clientX, e.clientY, 'edge', edge)
      })

      // 监听节点鼠标进入事件
      this.graph.on('node:mouseenter', ({ node }) => {
        this.connectionState.hoveredNode = node
        this.showNodePorts(node)
      })

      // 监听连接开始事件 - 添加自动端口选择
      this.graph.on('edge:connected', ({ edge, isNew }) => {
        console.log('连接完成:', edge)

        // 自动端口选择逻辑
        if (isNew) {
          const sourceNode = edge.getSourceNode()
          const targetNode = edge.getTargetNode()

          // if (sourceNode && targetNode) {
          //   const optimalPorts = this.calculateOptimalPorts(sourceNode, targetNode)

          //   // 更新连接的端口
          //   edge.setSource(sourceNode, {
          //     port: optimalPorts.source
          //   })
          //   edge.setTarget(targetNode, {
          //     port: optimalPorts.target
          //   })

          //   console.log('🔗 自动端口选择完成:', {
          //     sourcePort: optimalPorts.source,
          //     targetPort: optimalPorts.target,
          //     sourceNodeId: sourceNode.id,
          //     targetNodeId: targetNode.id
          //   })
          // }
          // 自动保存到localStorage
          this.saveCanvasToStorage()
        }
      })

      // 监听连接移动事件
      this.graph.on('edge:move', ({ edge }) => {
        console.log('连接移动:', edge)
      })

      // 鼠标进入节点时添加编辑按钮工具
      this.graph.on('node:mouseenter', ({ node }) => {
        // 只对HTML类型节点添加编辑按钮
        if (node.shape === 'markdown-node') {
          // 添加编辑按钮
          node.addTools({
            name: 'button',
            args: {
              markup: [
                {
                  tagName: 'circle',
                  attrs: {
                    r: 14,
                    fill: '#007bff',
                    stroke: '#fff',
                    'stroke-width': 2,
                    cursor: 'pointer'
                  }
                },
                {
                  tagName: 'text',
                  attrs: {
                    x: 0,
                    y: 0,
                    'text-anchor': 'middle',
                    'dominant-baseline': 'central',
                    fill: '#fff',
                    'font-size': 14,
                    'font-family': 'Arial',
                    cursor: 'pointer'
                  },
                  textContent: '✎'
                }
              ],
              x: '100%',
              y: 0,
              offset: { x: -8, y: 8 },
              onClick: ({ view }) => {
                const node = view.cell
                const nodeId = node.id || node.getId?.()
                const content = node.getData()?.content || ''

                console.log('🖱️ 编辑按钮点击:', {
                  nodeId,
                  nodeIdType: typeof nodeId,
                  nodeShape: node.shape,
                  hasGetId: typeof node.getId === 'function',
                  nodeData: node.getData(),
                  viewCell: !!view.cell
                })

                this.openEditDialog(nodeId, content)
              }
            }
          })

          // 添加折叠按钮
          node.addTools({
            name: 'button',
            args: {
              markup: [
                {
                  tagName: 'circle',
                  attrs: {
                    r: 14,
                    fill: '#28a745',
                    stroke: '#fff',
                    'stroke-width': 2,
                    cursor: 'pointer'
                  }
                },
                {
                  tagName: 'text',
                  attrs: {
                    x: 0,
                    y: 0,
                    'text-anchor': 'middle',
                    'dominant-baseline': 'central',
                    fill: '#fff',
                    'font-size': 12,
                    'font-family': 'Arial',
                    cursor: 'pointer'
                  },
                  textContent: '▼'
                }
              ],
              x: '100%',
              y: 0,
              offset: { x: -38, y: 8 },
              onClick: ({ view }) => {
                console.log('点击折叠')
                const node = view.cell
                const nodeView = this.graph.findViewByCell(node)

                if (nodeView && nodeView.container) {
                  const container = nodeView.container.querySelector('.markdown-node-content')


                  if (container) {
                    const isCollapsed = node?.data?.isCollapsed

                    if (isCollapsed) {
                      // 展开
                      container.style.display = 'block'
                      console.log('📖 节点内容已展开')

                      //设置 数据
                      node.setData({
                        isCollapsed: false,

                      })
                      if (node?.data?.containerBigHeight) {
                        node.prop('size/height', node?.data?.containerBigHeight)
                      }


                    } else {
                      const containerBig = nodeView.container.querySelector('.markdown-node-container')
                      var containerBigHeight = containerBig?.offsetHeight
                      console.log("🚀 ~ initGraph ~ containerBigHeight:", containerBigHeight)
                      // 折叠
                      container.style.display = 'none'
                      console.log('📕 节点内容已折叠')

                      //设置 数据
                      node.setData({
                        isCollapsed: true,
                        containerBigHeight
                      })
                      node.prop('size/height', 85)
                    }
                  }
                }


                this.saveCanvasToStorage()
              }
            }
          })

          // // 根据当前Transform状态添加相应的resize控制按钮
          // if (this.transformEnabled) {
          //   // Transform开启时显示关闭按钮
          //   node.addTools(this.createStopResizeButton())
          // } else {
          //   // Transform关闭时显示开启按钮
          //   node.addTools(this.createStartResizeButton())
          // }

        }
      })

      // 鼠标离开节点时的综合处理
      this.graph.on('node:mouseleave', ({ node }) => {
        // 移除所有按钮工具（编辑按钮、折叠按钮和resize控制按钮）
        if (node.shape === 'markdown-node' && node.hasTool('button')) {
          node.removeTools()
        }
        this.hideNodePorts(node)
      })

      // this.graph.use(
      //   new Selection({
      //     enabled: true,
      //     multiple: true,
      //     rubberband: true,
      //     movable: true,
      //     showNodeSelectionBox: true,
      //   }),
      // )

      // 初始化Transform插件，支持节点resize
      // this.initializeTransform()


      // 窗口大小变化时调整画板大小
      window.addEventListener('resize', this.handleResize)
    },

    /**
     * 添加初始节点
     */
    addInitialNodes() {
      // 创建根节点
      const rootNode = this.graph.addNode({
        x: 300,
        y: 200,
        width: 120,
        height: 60,
        label: '根节点',
        data: {
          nodeOrder: this.nodeOrderGlobe
        },
        // 添加连接点配置
        ports: {
          groups: {
            'connection-port': {
              position: 'absolute',
              attrs: {
                circle: {
                  r: 6,
                  magnet: true,
                  stroke: '#5F95FF',
                  strokeWidth: 2,
                  fill: '#fff',
                  style: {
                    visibility: 'hidden'
                  }
                }
              }
            }
          },
          items: [
            { id: 'top', group: 'connection-port', args: { x: '50%', y: 0 } },
            { id: 'right', group: 'connection-port', args: { x: '100%', y: '50%' } },
            { id: 'bottom', group: 'connection-port', args: { x: '50%', y: '100%' } },
            { id: 'left', group: 'connection-port', args: { x: 0, y: '50%' } }
          ]
        },
        attrs: {
          body: {
            stroke: '#5F95FF',
            strokeWidth: 2,
            fill: 'rgba(95,149,255,0.05)',
            rx: 6,
            ry: 6
          },
          label: {
            text: '开始',
            fontSize: 14,
            fill: '#262626'
          }
        }
      })

      // 递增节点顺序计数器
      this.nodeOrderGlobe++
      this.nodeCounter = 3
    },

    /**
     * 生成新节点 [生成节点]
     */
    async generateNode() {
      if (!this.inputText.trim()) return

      this.isLoading = true

      try {
        // // 模拟AI调用
        // const aiResponse = await this.callAI(this.inputText)




        //如果没有选中节点 就用最后一个加入的节点
        if (!this.selectedNode) {
          // 查找最后一个加入的节点（nodeOrder最大的节点）
          const lastNode = this.findLastAddedNode()
          if (lastNode) {
            this.selectedNode = {
              id: lastNode.id,
              label: lastNode.getLabel ? lastNode.getLabel() : (lastNode.getData()?.title || '节点')
            }
          }
        }

        // 创建新节点
        const newNode = this.createNewNode({
          inputText: this.inputText
        })


        // 如果有选中节点，创建连线
        if (this.selectedNode) {
          this.createConnection(this.selectedNode.id, newNode.id)
        }



        //开始初始化内容  异步
        this.callAI(this.inputText)?.then(aiResponse => {
          newNode.data?.setHtml?.(aiResponse)
          // 清空输入框
          this.inputText = ''

          //持久化
          this.saveCanvasToStorage()
        })

      } catch (error) {
        console.error('生成节点失败:', error)
        alert('生成节点失败，请重试')
      } finally {
        this.isLoading = false
      }
    },

    /**
     * 调用AI接口
     * @param {string} input - 用户输入
     * @returns {Promise<string>} AI响应
     */
    async callAI(input) {
      try {
        console.log('🤖 调用智谱AI:', input)

        const contextAskList = this.graph?.getNodes()?.map(item => {
          return item?.data?.title
        })
        console.log("🚀 ~ callAI ~ contextAskList:", contextAskList)

        const response = await fetch('https://open.bigmodel.cn/api/paas/v4/chat/completions', {
          method: 'POST',
          headers: {
            'Authorization': 'Bearer ca6a88f0d77243118f645bd726477c24.nA1YnQkFI0Dn3mvg',
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({
            model: 'glm-4.5-air',
            messages: [
              {
                role: 'system',
                content: '你是一个专业的技术助手，请用Markdown格式回答问题，包含标题、列表、代码块等格式。回答要详细且实用。'
              },
              {
                role: 'system',
                content: `这是我之前问过你的问题，上下文:${contextAskList?.join('\n\n')}`
              },
              {
                role: 'user',
                content: input
              }
            ],
            temperature: 0.7,
            max_tokens: 1000
          })
        })

        debugger

        if (!response.ok) {
          throw new Error(`API调用失败: ${response.status} ${response.statusText}`)
        }

        const data = await response.json()
        const aiResponse = data?.choices?.[0].message?.content || data?.choices?.[0].message?.reasoning_content
        console.log('✅ AI响应成功:', aiResponse.substring(0, 100) + '...')
        return aiResponse

      } catch (error) {
        console.error('❌ AI调用错误:', error)
        console.log('🔄 使用降级响应')

        // 降级到模拟响应
        return this.fallbackResponse(input)
      }
    },

    /**
     * 降级响应机制
     * @param {string} input - 用户输入
     * @returns {string} 模拟AI响应
     */
    fallbackResponse(input) {
      const responses = [
        `# ${input}的分析\n\n这是基于**${input}**的详细分析：\n\n- 关键点1\n- 关键点2\n- 关键点3\n\n\`代码示例\``,
        `## ${input}详解\n\n> 这是关于${input}的重要说明\n\n**核心概念：**\n1. 第一个要点\n2. 第二个要点\n\n\`\`\`javascript\nconsole.log('${input}');\n\`\`\``,
        `### ${input}实现方案\n\n*实现步骤：*\n\n1. **准备阶段**\n   - 分析需求\n   - 设计方案\n\n2. **开发阶段**\n   - 编写代码\n   - 测试功能`,
        `# ${input}相关概念\n\n这是一个关于**${input}**的概念说明。\n\n> 重要提示：请仔细阅读以下内容\n\n- 概念A：*详细说明*\n- 概念B：\`技术术语\`\n- 概念C：[链接示例](https://example.com)`,
        `## ${input}应用场景\n\n**主要应用：**\n\n1. 场景一\n   - 具体用法\n   - 注意事项\n\n2. 场景二\n   - \`代码片段\`\n   - *最佳实践*\n\n> 总结：${input}在实际项目中非常有用`
      ]

      return responses[Math.floor(Math.random() * responses.length)]
    },

    /**
     * 创建新节点
     * @param {string} inputText - 节点内容
     * @returns {Object} 新创建的节点
     */
    createNewNode(_options) {
      var _selectedNode = this.graph?.getNodes()?.find((item) => {
        return this.selectedNode?.id && item?.id == this.selectedNode?.id
      })
      // 计算新节点位置
      let x = _selectedNode?.position()?.x + (_selectedNode?.size()?.width / 2)
      let y = _selectedNode?.position()?.y + _selectedNode?.size()?.height + 33 + Math.random() * 300

      if (!_selectedNode) {
        x = 200 + Math.random() * 100
        y = Math.random() * 100 - 50
      }

      // 判断内容是否包含Markdown语法
      // const hasMarkdownSyntax = /[#*`\[\]_~]/.test(content)
      const hasMarkdownSyntax = true

      let newNode

      if (hasMarkdownSyntax) {
        // 创建富文本HTML节点
        newNode = this.graph.addNode({
          shape: 'markdown-node',
          x,
          y,
          data: {
            nodeOrder: this.nodeOrderGlobe,
            content: '内容加载中。。。',
            title: `节点${this.nodeCounter}-${_options?.inputText}`,
            nodeType: 'ai-generated'
          }
        })
      } else {
        // 创建普通节点
        newNode = this.graph.addNode({
          x,
          y,
          width: 140,
          height: 70,
          label: content,
          data: {
            nodeOrder: this.nodeOrderGlobe
          },
          attrs: {
            body: {
              stroke: '#ff7875',
              strokeWidth: 2,
              fill: 'rgba(255,120,117,0.05)',
              rx: 6,
              ry: 6
            },
            label: {
              // text: content.length > 15 ? content.substring(0, 15) + '...' : content,
              fontSize: 12,
              fill: '#262626',
              textWrap: {
                width: 120,
                height: 50,
                ellipsis: true
              }
            }
          }
        })
      }

      // 递增节点顺序计数器
      this.nodeOrderGlobe++
      this.nodeCounter++

      // 自动保存到localStorage
      this.saveCanvasToStorage()

      return newNode
    },

    /**
     * 查找最后一个加入的节点（基于nodeOrder）
     * @returns {Object|null} 最后加入的节点或null
     */
    findLastAddedNode() {
      const nodes = this.graph.getNodes()
      let lastNode = null
      let maxOrder = -1

      nodes.forEach(node => {
        const nodeData = node.getData()
        const nodeOrder = nodeData?.nodeOrder || 0
        if (nodeOrder > maxOrder) {
          maxOrder = nodeOrder
          lastNode = node
        }
      })

      return lastNode
    },

    /**
     * 创建节点间连接
     * @param {string} sourceId - 源节点ID
     * @param {string} targetId - 目标节点ID
     * @param {boolean} autoPortSelection - 是否启用自动端口选择
     */
    createConnection(sourceId, targetId, autoPortSelection = true) {
      let sourcePort = 'bottom'
      let targetPort = 'top'

      // 如果启用自动端口选择，计算最优端口
      if (autoPortSelection) {
        // const optimalPorts = this.calculateOptimalPorts(sourceId, targetId)
        // sourcePort = optimalPorts.source
        // targetPort = optimalPorts.target
      }

      console.log(`🔗 创建连接: ${sourceId}(${sourcePort}) -> ${targetId}(${targetPort})`)

      this.graph.addEdge({
        source: { cell: sourceId, port: sourcePort },
        target: { cell: targetId, port: targetPort },
        attrs: {
          line: {
            stroke: '#222',
            strokeWidth: 6,
            targetMarker: {
              name: 'classic',
              size: 8
            }
          }
        }
      })

      // 自动保存到localStorage
      this.saveCanvasToStorage()
    },

    /**
     * 计算最优端口组合
     * @param {string} sourceId - 源节点ID
     * @param {string} targetId - 目标节点ID
     * @returns {Object} 最优端口组合 {source: string, target: string}
     */
    calculateOptimalPorts(sourceId, targetId) {
      const sourceNode = this.graph.getCellById(sourceId)
      const targetNode = this.graph.getCellById(targetId)

      if (!sourceNode || !targetNode) {
        console.warn('⚠️ 节点未找到，使用默认端口')
        return { source: 'bottom', target: 'top' }
      }

      // 获取节点位置和尺寸
      const sourcePos = sourceNode.position()
      const targetPos = targetNode.position()
      const sourceSize = sourceNode.size()
      const targetSize = targetNode.size()

      // 计算节点中心点
      const sourceCenterX = sourcePos.x + sourceSize.width / 2
      const sourceCenterY = sourcePos.y + sourceSize.height / 2
      const targetCenterX = targetPos.x + targetSize.width / 2
      const targetCenterY = targetPos.y + targetSize.height / 2

      // 计算相对位置
      const deltaX = targetCenterX - sourceCenterX
      const deltaY = targetCenterY - sourceCenterY

      console.log(`📍 节点位置分析: deltaX=${deltaX.toFixed(1)}, deltaY=${deltaY.toFixed(1)}`)

      // 根据相对位置选择最优端口
      let sourcePort, targetPort

      // 判断主要方向（水平或垂直）
      if (Math.abs(deltaX) > Math.abs(deltaY)) {
        // 水平方向为主
        if (deltaX > 0) {
          // 目标在右侧
          sourcePort = 'right'
          targetPort = 'left'
        } else {
          // 目标在左侧
          sourcePort = 'left'
          targetPort = 'right'
        }
      } else {
        // 垂直方向为主
        if (deltaY > 0) {
          // 目标在下方
          sourcePort = 'bottom'
          targetPort = 'top'
        } else {
          // 目标在上方
          sourcePort = 'top'
          targetPort = 'bottom'
        }
      }

      console.log(`🎯 选择端口: source=${sourcePort}, target=${targetPort}`)

      return { source: sourcePort, target: targetPort }
    },

    /**
     * 显示右键菜单
     */
    showContextMenu(x, y, type = 'blank', target = null) {
      this.contextMenu.visible = true
      this.contextMenu.x = x
      this.contextMenu.y = y

      // 检查节点是否处于编辑模式
      if (type === 'node' && EditableNodeController.currentEditingNode &&
        EditableNodeController.currentEditingNode.cell === target) {
        this.contextMenu.type = 'editing'
      } else {
        this.contextMenu.type = type
      }

      this.contextMenu.target = target

      // 添加全局点击事件监听，用于隐藏菜单
      document.addEventListener('click', this.hideContextMenu)
    },

    /**
     * 隐藏右键菜单
     */
    hideContextMenu() {
      this.contextMenu.visible = false
      this.contextMenu.type = 'blank'
      this.contextMenu.target = null
      document.removeEventListener('click', this.hideContextMenu)
    },

    /**
     * 在指定位置创建节点
     */
    createNodeAtPosition(x, y) {
      // 将屏幕坐标转换为画板坐标
      const localPoint = this.graph.clientToLocal(x, y)

      // 创建富文本HTML节点
      const node = this.graph.addNode({
        shape: 'markdown-node',
        // shape: 'markdown-node',
        x: localPoint.x - 125, // 减去节点宽度的一半
        y: localPoint.y - 75,  // 减去节点高度的一半
        data: {
          content: `# 新节点${this.nodeCounter}\n`,
          title: `节点${this.nodeCounter}`,
          nodeType: 'manual'
        }
      })

      this.nodeCounter++

      // 自动保存到localStorage
      this.saveCanvasToStorage()

      return node
    },

    /**
     * 从右键菜单创建节点
     */
    createNodeFromContextMenu() {
      // 将屏幕坐标转换为画板坐标
      const canvasRect = this.$refs.canvasContainer.getBoundingClientRect()
      const x = this.contextMenu.x - canvasRect.left
      const y = this.contextMenu.y - canvasRect.top

      this.createNodeAtPosition(x, y)
      this.hideContextMenu()
    },

    /**
     * 显示节点连接点
     */
    showNodePorts(node) {
      const ports = node.getPorts()
      ports.forEach(port => {
        node.setPortProp(port.id, 'attrs/circle/style/visibility', 'visible')
      })
    },

    /**
     * 隐藏节点连接点
     */
    hideNodePorts(node) {
      const ports = node.getPorts()
      ports.forEach(port => {
        node.setPortProp(port.id, 'attrs/circle/style/visibility', 'hidden')
      })
    },

    /**
     * 新增节点并使用AI生成内容
     */
    async addNodeWithAI() {
      if (this.contextMenu.target) {
        const sourceEditNode = this.contextMenu.target
        const sourceNodeId = sourceEditNode.id || sourceEditNode.getId?.()

        // 弹出输入框获取prompt
        const prompt = window.prompt('请输入您想要AI回答的问题：')
        console.log("🚀 ~ addNodeWithAI ~ prompt:", prompt)
        if (!prompt || prompt.trim() === '') {
          this.hideContextMenu()
          return
        }

        // 获取源节点位置
        const sourcePosition = sourceEditNode.getPosition()

        // 创建目标节点
        const targetNode = this.createNewNode({
          inputText: prompt
        })

        // 计算最优端口连接
        const optimalPorts = this.calculateOptimalPorts(sourceEditNode.id, targetNode.id)

        // 连线
        this.graph.addEdge({
          source: { cell: sourceEditNode, port: optimalPorts.source },
          target: { cell: targetNode, port: optimalPorts.target },
          attrs: {
            line: {
              stroke: '#A2B1C3',
              strokeWidth: 2,
              targetMarker: {
                name: 'block',
                width: 12,
                height: 8
              }
            }
          }
        })

        console.log('创建AI问答节点:', { sourceNodeId, prompt })

        // 异步调用AI获取回答
        try {
          // 这里可以集成真实的AI API
          this.callAI(prompt)?.then(aiResponse => {
            // 更新目标节点内容
            targetNode.data?.setHtml?.(aiResponse)

            //持久化
            this.saveCanvasToStorage()


            console.log('AI回答已更新到目标节点')

          })


        } catch (error) {
          console.error('AI调用失败:', error)
          targetNode.setData({
            content: '抱歉，AI服务暂时不可用。'
          })
        }

        // 保存到localStorage
        this.saveCanvasToStorage()
      }
      this.hideContextMenu()
    },

    /**
     * 重新询问AI
     */
    async reaskAI() {
      if (this.contextMenu.target) {
        const currentNode = this.contextMenu.target
        const nodeId = currentNode.id || currentNode.getId?.()

        // 弹出输入框获取prompt
        const prompt = window.prompt('请输入您想要AI回答的问题：')
        console.log("🚀 ~ reaskAI ~ prompt:", prompt)
        if (!prompt || prompt.trim() === '') {
          this.hideContextMenu()
          return
        }

        console.log('重新询问AI:', { nodeId, prompt })

        // 异步调用AI获取回答
        try {
          this.callAI(prompt)?.then(aiResponse => {
            // 更新当前节点内容
            currentNode.data?.setHtml?.(aiResponse)

            // 持久化
            this.saveCanvasToStorage()

            console.log('AI回答已更新到当前节点')
          })
        } catch (error) {
          console.error('AI调用失败:', error)
          currentNode.setData({
            content: '抱歉，AI服务暂时不可用。'
          })
        }

        // 保存到localStorage
        this.saveCanvasToStorage()
      }
      this.hideContextMenu()
    },

    /**
     * 编辑节点
     */
    editNode() {
      if (this.contextMenu.target) {
        const node = this.contextMenu.target
        const nodeId = node.id || node.getId?.()

        // 获取节点的DOM元素
        const nodeView = this.graph.findViewByCell(node)
        if (nodeView && nodeView.container) {
          // 创建EditableNodeController实例并进入编辑模式
          const controller = new EditableNodeController(this.graph,
            node,
            nodeView.container?.querySelector('.markdown-node-container'),
            nodeView.container?.querySelector('.markdown-node-content'))
          controller.enterEditMode()
          console.log('开启节点编辑模式:', nodeId)
        }
      }
      this.hideContextMenu()
    },

    /**
     * 保存编辑节点 保存保存保存
     */
    saveEditNode() {

      // 获取当前正在编辑的节点控制器
      if (EditableNodeController.currentEditingNode) {
        EditableNodeController.currentEditingNode.exitEditMode(true)
        console.log('保存编辑内容')
      } else {
        const sourceEditNode = this.contextMenu.target
        var nodeview = this.graph?.findViewByCell(sourceEditNode)
        var newContent = nodeview?.container?.querySelector('.markdown-node-content')?.innerHTML

        var newTitle = nodeview?.container?.querySelector('.title-container')?.innerHTML
        sourceEditNode?.setData({
          content: newContent,
          title: newTitle
        })

        this.saveCanvasToStorage()
      }
      this.hideContextMenu()
    },

    /**
     * 取消保存编辑节点
     */
    cancelEditNode() {
      // 获取当前正在编辑的节点控制器
      if (EditableNodeController.currentEditingNode) {
        EditableNodeController.currentEditingNode.exitEditMode(false)
        console.log('取消保存编辑内容')
      }
      this.hideContextMenu()
    },

    /**
     * 删除节点
     */
    deleteNode() {
      if (this.contextMenu.target) {
        this.graph.removeNode(this.contextMenu.target)
        console.log('删除节点:', this.contextMenu.target.id)
        // 自动保存到localStorage
        this.saveCanvasToStorage()
      }
      this.hideContextMenu()
    },

    /**
     * 删除线条
     */
    deleteEdge() {
      if (this.contextMenu.target) {
        this.graph.removeEdge(this.contextMenu.target)
        console.log('删除线条:', this.contextMenu.target.id)
        // 自动保存到localStorage
        this.saveCanvasToStorage()
      }
      this.hideContextMenu()
    },

    /**
     * 处理窗口大小变化
     */
    handleResize() {
      if (this.graph && this.$refs.canvasWrapper) {
        this.graph.resize(
          this.$refs.canvasWrapper.clientWidth,
          this.$refs.canvasWrapper.clientHeight
        )
      }
    },

    /**
     * 打开编辑弹窗
     */
    openEditDialog(nodeId, content) {
      console.log('📝 编辑对话框打开:', {
        nodeId: nodeId,
        nodeIdType: typeof nodeId,
        nodeExists: !!this.graph.getCellById(nodeId),
        allNodes: this.graph.getNodes().map(n => ({ id: n.id, shape: n.shape })),
        content: content
      })

      this.editingNodeId = nodeId
      this.editContent = content
      this.isEditDialogVisible = true
    },

    /**
     * 关闭编辑弹窗
     */
    closeEditDialog() {
      this.isEditDialogVisible = false
      this.editContent = ''
      this.editingNodeId = null
    },

    /**
     * 创建开始resize按钮
     */
    createStartResizeButton() {
      return {
        name: 'button',
        args: {
          markup: [
            {
              tagName: 'circle',
              attrs: {
                r: 14,
                fill: '#28a745', // 绿色
                stroke: '#fff',
                'stroke-width': 2,
                cursor: 'pointer'
              }
            },
            {
              tagName: 'text',
              attrs: {
                x: 0,
                y: 0,
                'text-anchor': 'middle',
                'dominant-baseline': 'central',
                fill: '#fff',
                'font-size': 12,
                cursor: 'pointer'
              },
              textContent: '⤢'
            }
          ],
          x: '100%',
          y: 0,
          offset: { x: -38, y: 8 }, // 与编辑按钮错开位置
          onClick: () => {
            this.startResize()
          }
        }
      }
    },

    /**
     * 创建结束resize按钮
     */
    createStopResizeButton() {
      return {
        name: 'button',
        args: {
          markup: [
            {
              tagName: 'circle',
              attrs: {
                r: 14,
                fill: '#dc3545', // 红色
                stroke: '#fff',
                'stroke-width': 2,
                cursor: 'pointer'
              }
            },
            {
              tagName: 'text',
              attrs: {
                x: 0,
                y: 0,
                'text-anchor': 'middle',
                'dominant-baseline': 'central',
                fill: '#fff',
                'font-size': 12,
                cursor: 'pointer'
              },
              textContent: '✕'
            }
          ],
          x: '100%',
          y: 0,
          offset: { x: -38, y: 8 },
          onClick: () => {
            this.stopResize()
          }
        }
      }
    },

    /**
     * 保存节点内容
     */
    saveNodeContent({ nodeId, content }) {
      console.log('💾 保存节点内容:', {
        nodeId: nodeId,
        nodeIdType: typeof nodeId,
        newContent: content?.substring(0, 50) + '...'
      })

      // 尝试多种方式获取节点 - 方案A实现
      let node = this.graph.getCellById(nodeId)

      try {
        // 更新节点数据
        const oldData = node.getData() || {}
        const newData = {
          ...oldData,
          content: content
        }

        node.setData(newData)
        console.log("🚀 ~ saveNodeContent ~ 修改的数据 newData:", newData)


        // 强制重新渲染
        this.graph.trigger('node:change:data', { node, current: newData })

        // 重新渲染节点
        // if (node.shape === 'markdown-node') {
        //   // 触发HTML节点重新渲染
        //   const htmlContent = node.getView()?.cell?.getHTML?.()
        //   node.attr('html', htmlContent || '')
        //   console.log('🎨 HTML节点重新渲染完成')
        // }

      } catch (error) {
        console.error('❌ 保存节点内容失败:', error)
        alert('保存失败，请重试')
      } finally {
        this.closeEditDialog()
      }
    }
  },

  beforeDestroy() {
    // 清理事件监听器
    window.removeEventListener('resize', this.handleResize)
    document.removeEventListener('click', this.hideContextMenu)

    // 销毁画板实例
    if (this.graph) {
      this.graph.dispose()
    }
  }
}
</script>

<style scoped>
.canvas-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: #f0f2f5;
}

.canvas-wrapper {
  flex: 1;
  position: relative;
  overflow: hidden;
}

#canvas-container {
  width: 100%;
  height: 100%;
}

.toolbar {
  position: absolute;
  top: 16px;
  right: 16px;
  display: flex;
  gap: 8px;
  z-index: 1000;
}

.toolbar-btn {
  padding: 8px 16px;
  background: white;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.3s;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.toolbar-btn:hover {
  background: #f5f5f5;
  border-color: #40a9ff;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.toolbar-btn:active {
  transform: translateY(1px);
}

.toolbar-btn.clear-btn {
  background: #ff4d4f;
  color: white;
  border-color: #ff4d4f;
}

.toolbar-btn.clear-btn:hover {
  background: #ff7875;
  border-color: #ff7875;
}

.input-section {
  background: white;
  border-top: 1px solid #e8e8e8;
  padding: 16px 24px;
  box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.1);
}

.input-wrapper {
  display: flex;
  gap: 12px;
  margin-bottom: 8px;
}

.ai-input {
  flex: 1;
  padding: 8px 12px;
  border: 1px solid #d9d9d9;
  border-radius: 6px;
  font-size: 14px;
  outline: none;
  transition: border-color 0.3s;
}

.ai-input:focus {
  border-color: #5F95FF;
  box-shadow: 0 0 0 2px rgba(95, 149, 255, 0.2);
}

.ai-input:disabled {
  background-color: #f5f5f5;
  cursor: not-allowed;
}

.generate-btn {
  padding: 8px 16px;
  background: #5F95FF;
  color: white;
  border: none;
  border-radius: 6px;
  font-size: 14px;
  cursor: pointer;
  transition: background-color 0.3s;
  white-space: nowrap;
}

.generate-btn:hover:not(:disabled) {
  background: #4c7dff;
}

.generate-btn:disabled {
  background: #d9d9d9;
  cursor: not-allowed;
}

.status-info {
  font-size: 12px;
  color: #8c8c8c;
  display: flex;
  align-items: center;
  gap: 8px;
}

.status-info span {
  padding: 2px 8px;
  background: #f0f0f0;
  border-radius: 4px;
}

/* 右键菜单样式 */
.context-menu {
  position: fixed;
  background: white;
  border: 1px solid #e8e8e8;
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  min-width: 120px;
  padding: 4px 0;
}

.menu-item {
  padding: 8px 16px;
  cursor: pointer;
  font-size: 14px;
  color: #262626;
  transition: background-color 0.2s;
}

.menu-item:hover {
  background-color: #f5f5f5;
}

.menu-item:active {
  background-color: #e6f7ff;
}



/* 响应式设计 */
@media (max-width: 768px) {
  .input-section {
    padding: 12px 16px;
  }

  .input-wrapper {
    flex-direction: column;
    gap: 8px;
  }

  .generate-btn {
    width: 100%;
  }

  .markdown-node-content,
  .rich-text-node-container {
    max-width: 250px;
  }
}
</style>
